//: Playground - noun: a place where people can play

import UIKit

//定义语法
class SomeClass {
  
    var width = 0
    var height = 0
}

//class Resolution {
//    
//    var someclass = SomeClass()
//    var interlaced = false
//    var frametate = 0.0
//    var name : String?
//}
struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

let vga = Resolution(width: 10, height: 10)

let videoMode = VideoMode()

//结构和枚举类型是数值类型

//类是引用类型

let tenEighty = VideoMode()
tenEighty.resolution = vga
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
tenEighty.frameRate

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")


//可以通过如下两个操作来判断两个常量或者变量是否引用的是同一个类的实例：

//相同的实例(===)
//
//不同的实例(!==)

if tenEighty === alsoTenEighty{
    
    print("tenEighty and alsoTenEighty refer to the same Resolution instance.")
    
}

if tenEighty !== alsoTenEighty {
    
    
}

//Lazy Stored Properties（懒惰存储属性?)
//懒惰存储属性是当它第一次被使用时才进行初值计算。通过在属性声明前加上@lazy来标识一个懒惰存储属性.
//必须声明懒惰存储属性为变量属性（通过var），因为它的初始值直到实例初始化完成之后才被检索。常量属性在实例初始化完成之前就应该被赋值，因此常量属性不能够被声明为懒惰存储属性。

class DataImporter {
    
    var fileName = "data.txt"
    
}

class DataManager {
    
    lazy var importer = DataImporter()
    var data = [String]()
}


let manager = DataManager()

manager.data += ["Some data"]
manager.data += ["Some more data"]

//DataImporter的实例importer只有在当它在第一次被访问时才被创建。例如它的fileName属性需要被访问时：

print(manager.importer.fileName)
/**
 *  计算属性
 */

//除了存储属性，类、结构和枚举能够定义计算属性。计算属性并不存储值，它提供getter和可选的setter来间接地获取和设置其它的属性和值。

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter){
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }

    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")


//setter声明的简略写法
struct AlternativeRect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

/**
*  只读计算属性
*/

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}

let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")

/**
*  属性观察者
*/

//willSet：设置值前被调用
//didSet：设置值后立刻被调用

class StepCounter {
    var totalSteps: Int = 0 {
        //属性初始化时，willSet和didSet不会被调用
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        didSet {
            if totalSteps > oldValue  {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896

//类型属性,类型内部使用
struct SomeStructure {
     var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        // return an Int value here
        return 10
    }
}
var somestrcut = SomeStructure()

somestrcut.storedTypeProperty = "some"

enum SomeEnumeration {
    
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        // return an Int value here
        return 20
    }
}


class MyClass {
    
    class var computedTypeProperty: Int {
        // return an Int value here
        return 30
    }
}

var myclass = MyClass()

/**
 *  查询与设置类型属性
 */
struct AudioChannel {
    static let thresholdLevel = 10
    static var maxInputLevelForAllChannels = 0
    var currentLevel: Int = 0 {
        didSet {
            if currentLevel > AudioChannel.thresholdLevel {
                //cap the new audio level to the threshold level
                currentLevel = AudioChannel.thresholdLevel
            }
            if currentLevel > AudioChannel.maxInputLevelForAllChannels {
                // store this as the new overall maximum input level
                AudioChannel.maxInputLevelForAllChannels = currentLevel
            }
        }
    }
}

var leftChannel = AudioChannel()
var rightChannel = AudioChannel()

leftChannel.currentLevel = 7
print(leftChannel.currentLevel)
// prints "7"
print(AudioChannel.maxInputLevelForAllChannels)
// prints "7”

//如果像设置右通道的currentlevel为11，它的值将被截短成为10，而且maxInputLevelForAllChannels的值也将更新为10:
rightChannel.currentLevel = 11
print(rightChannel.currentLevel)
// prints "10"
print(AudioChannel.maxInputLevelForAllChannels)






